package com.huiquan.analysis.job;

import com.huiquan.analysis.dao.CheckDataDao;
import com.huiquan.analysis.domain.CheckDataSql;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.utils.SpringInvokeUtils;
import com.huiquan.icd.dao.IcdCodeDao;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.File;
import java.util.*;
import com.huiquan.framework.utils.EMailUtil;


/**
 * Description: 校验错误数据
 *
 * @author fzl
 * @Date 14/9/22
 * @since Ver 1.0
 */
@Service("checkDataService")
public class CheckDataJob extends BaseService {

    @Autowired
    private CheckDataDao checkDataDao;
    @Autowired
    private EMailUtil eMailUtil;
    @Value("${check.data.xml.address}")
    private String checkXmlAddress;

    @SuppressWarnings("rawtypes")
    public void checkData(String type) throws Exception {
        if (StringUtils.equalsIgnoreCase(type, "sql")) {
            // 用SQL进行校验
            List<CheckDataSql> list = new ArrayList<>();
            list = checkDataDao.retrieveList();
            // 获取到校验列表
            for (CheckDataSql value : list) {
                String rtn = "";
                String sql = value.getCheckSql();
                LOGGER.info("sql=" + sql);
                String regularExpression = value.getRegularExpression();
                String remark = value.getRemark();
                String email = value.getEmail();
                String resultSql = value.getCheckResultSql();
                Map<String, Object> param = new HashMap<>();
                param.put("checkSql", sql);
                int checkValue = checkDataDao.checkSqlCount(param);
                // 判断是否要用校验表达式
                if (StringUtils.isNotBlank(regularExpression)) {
                    ScriptEngineManager manager = new ScriptEngineManager();
                    ScriptEngine engine = manager.getEngineByName("js");
                    engine.put("a", checkValue);
                    Object result = null;
                    try {
                        result = engine.eval(regularExpression);
                        if (StringUtils.equalsIgnoreCase(result.toString(), "false")) {
                            String resultStr = "";
                            if (StringUtils.isNotBlank(resultSql)) {
                                resultStr = getResultContent(resultSql, remark);
                                resultStr = "\n" + resultStr;
                            }
                            rtn = "sql校验" + remark + "校验失败" + resultStr + "|" + email;
                        } else {
                            LOGGER.info("sql校验" + remark + "校验结果类型:" + result.getClass().getName() + ",校验结果:" + result);
                        }
                    } catch (ScriptException e) {
                        LOGGER.error(e.getMessage());
                        e.printStackTrace();
                        rtn = "sql校验" + remark + "校验表达式配置有误" + "|" + email;
                    } catch (Exception e2) {
                        LOGGER.info("sql校验" + remark + "校验失败");
                        throw e2;
                    }
                } else {
                    // 不存在表达式。如果sql查询count大于0就说明有错误数据
                    if (checkValue > 0) {
                        String result = "";
                        if (StringUtils.isNotBlank(resultSql)) {
                            result = getResultContent(resultSql, remark);
                            result = "\n" + result;
                        }
                        rtn = "sql校验" + remark + result + "校验失败" + "|" + email;
                    }
                }
                if (StringUtils.isNotBlank(rtn)) {
                    String[] a = rtn.split("\\|");
                    if (a.length > 1) {
                        List<String> address = new ArrayList<>();
                        address.add(a[1]);
                        eMailUtil.sendBatchEmail(a[0], "标注系统数据校验失败", address);
                    }
                }
            }
        } else if (StringUtils.equalsIgnoreCase(type, "java")) {
            // 读取xml中的配置文件
            try {
                // 获取数据库中使用java代码校验的类数据
                File f = new File(this.getClass().getClassLoader().getResource("/").getFile() + checkXmlAddress);
                SAXReader reader = new SAXReader();
                Document doc = reader.read(f);
                Element root = doc.getRootElement();
                Element checkValue;
                for (Iterator i = root.elementIterator("CHECK_VALUE"); i.hasNext(); ) {
                    checkValue = (Element) i.next();
                    String className = checkValue.elementText("CLASS");
                    String method = checkValue.elementText("METHOD");
                    Map<String, Object> map = getParamter(checkValue);
                    SpringInvokeUtils.invoke(className, method, (Class[]) map.get("class"),
                            (Object[]) map.get("value"));
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
        }
        return;
    }

    /**
     * 获取提示信息
     *
     * @param resultSql
     * @return
     */
    private String getResultContent(String resultSql, String remark) {
        StringBuffer result = new StringBuffer();
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("checkSql", resultSql);
            List<Map<String, Object>> resultList = checkDataDao.checkSqlResult(param);
            if (resultList != null && resultList.size() > 0) {
                for (Map<String, Object> resultValue : resultList) {
                    for (Map.Entry<String, Object> entry : resultValue.entrySet()) {
                        result.append(entry.getValue()).append(",");
                    }
                    result = new StringBuffer(result.substring(0, result.length() - 1));
                    result.append(";");
                }
            }
        } catch (Exception e) {
            LOGGER.info("sql校验该sql执行有误:" + remark);
        }
        return result.toString();
    }

    @SuppressWarnings("rawtypes")
    private Map<String, Object> getParamter(Element checkValue) throws ClassNotFoundException {
        Element param;
        List<Class> classList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        Map<String, Object> rtnMap = new HashMap<>();
        for (Iterator i = checkValue.elementIterator("PARAMETER"); i.hasNext(); ) {
            param = (Element) i.next();
            String type = param.elementText("PARAMETER_TYPE");
            String value = param.elementText("PARAMETER_VALUE");
            classList.add(Class.forName(type));
            valueList.add(value);
        }
        rtnMap.put("class", classList.toArray(new Class[0]));
        rtnMap.put("value", valueList.toArray(new Object[0]));
        return rtnMap;
    }
}
